package practice_bank;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 夫妻共同账户类
 */
class JointAccount {
    private double balance; // 账户余额
    private Lock lock = new ReentrantLock(); // 创建Lock对象
    public JointAccount(double initialBalance) {
        this.balance = initialBalance;
    }

    // 获取当前余额
    public double getBalance() {
        return balance;
    }

    /**
     * 取款方法（非线程安全版本）
     * @param amount 取款金额
     * @param name 取款人姓名
     * @return 是否取款成功
     */
    public boolean withdraw(double amount, String name) {
        if (balance >= amount) {
            // 模拟网络延迟或处理时间
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(name + "准备取款" + amount + "元");
            balance -= amount;
            System.out.println(name + "完成取款，余额: " + balance);
            return true;
        }
        System.out.println(name + "取款失败，余额不足");
        return false;
    }

    /**
     * 线程安全的取款方法（同步版本）
     * @param amount 取款金额
     * @param name 取款人姓名
     * @return 是否取款成功
     */
    public synchronized boolean safeWithdraw(double amount, String name) {
        if (balance >= amount) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(name + "准备取款" + amount + "元");
            balance -= amount;
            System.out.println(name + "完成取款，余额: " + balance);
            return true;
        }
        System.out.println(name + "取款失败，余额不足");
        return false;
    }


    // 同步代码块实现
    public boolean withdrawWithSyncBlock(double amount, String name) {
        // 同步代码块，使用this作为锁对象
        synchronized (this) {
            if (balance >= amount) {
                try {
                    Thread.sleep(100); // 模拟处理时间
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println(name + "准备取款" + amount + "元");
                balance -= amount;
                System.out.println(name + "完成取款，余额: " + balance);
                return true;
            }
            System.out.println(name + "取款失败，余额不足");
            return false;
        }
    }
    // 同步方法实现
    public synchronized boolean withdrawWithSyncMethod(double amount, String name) {
        if (balance >= amount) {
            try {
                Thread.sleep(100); // 模拟处理时间
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(name + "准备取款" + amount + "元");
            balance -= amount;
            System.out.println(name + "完成取款，余额: " + balance);
            return true;
        }
        System.out.println(name + "取款失败，余额不足");
        return false;
    }

    // Lock锁实现
    public boolean withdrawWithLock(double amount, String name) {
        lock.lock(); // 获取锁
        try {
            if (balance >= amount) {
                try {
                    Thread.sleep(100); // 模拟处理时间
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println(name + "准备取款" + amount + "元");
                balance -= amount;
                System.out.println(name + "完成取款，余额: " + balance);
                return true;
            }
            System.out.println(name + "取款失败，余额不足");
            return false;
        } finally {
            lock.unlock(); // 释放锁
        }
    }
}

